﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Data;
using System.Windows.Media;
using System.Windows;
using System.Diagnostics.Contracts;
using ShredTheLog.Api.DataContracts;
using ShredTheLog.Api;
using System.Reflection;

namespace ShredTheLog.Converters
{
    [ValueConversion(typeof(IBasicUserInfo), typeof(ImageSource))]
    public sealed class OdigoAvatarConverter : ConverterBase, IValueConverter
    {
        private static AvatarDescriptor[] _avatars;
        public static AvatarDescriptor[] Avatars
        {
            get
            {
                if (_avatars == null)
                {
                    var rd = new ResourceDictionary() { Source = new Uri(@"pack://application:,,,/" + Assembly.GetExecutingAssembly().FullName + ";component/Avatars/Avatars.xaml") };
                    _avatars = (AvatarDescriptor[])rd["Avatars"];
                }
                return _avatars;
            }
        }

        private static readonly Random _rnd = new Random();
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            var user = value as IBasicUserInfo;
            // Здесь может быть null, так как загрузка профайла пользователя при открытии карточки производится асинхронно.
            if (user != null)
                return Convert(user);
            else
                return null;
        }

        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            throw new NotSupportedException();
        }

        public static ImageSource Convert(IBasicUserInfo user)
        {
            Contract.Requires(user != null);

            AvatarGender gender = user.Gender == Gender.Male ? AvatarGender.Male : AvatarGender.Female;
            AvatarAge age = user.Age < 20 ? AvatarAge.Young : (user.Age < 40 ? AvatarAge.MiddleAged : AvatarAge.Old);
            AvatarEthnicity ethnicity;
            switch (user.Country)
            {
                case Country.Afghanistan:
                case Country.Albania:
                case Country.Algeria:
                case Country.Armenia:
                case Country.Azerbaijan:
                case Country.Bahrain:
                case Country.Egypt:
                case Country.Georgia:
                case Country.India:
                case Country.Iran:
                case Country.Iraq:
                case Country.Kazakhstan:
                case Country.Kuwait:
                case Country.Kyrgyzstan:
                case Country.Lebanon:
                case Country.Libya:
                case Country.Nepal:
                case Country.Oman:
                case Country.Pakistan:
                case Country.Qatar:
                case Country.SaudiArabia:
                case Country.SriLanka:
                case Country.Syria:
                case Country.Tajikistan:
                case Country.Turkey:
                case Country.Turkmenistan:
                case Country.UnitedArabEmirates:
                case Country.Uzbekistan:
                case Country.Yemen:
                    ethnicity = AvatarEthnicity.Arab;
                    break;
                case Country.Angola:
                case Country.Benin:
                case Country.Botswana:
                case Country.BurkinaFaso:
                case Country.Burundi:
                case Country.Cameroon:
                case Country.CentralAfricanRepublic:
                case Country.Chad:
                case Country.Congo:
                case Country.Djibouti:
                case Country.EquatorialGuinea:
                case Country.Ethiopia:
                case Country.Gabon:
                case Country.Gambia:
                case Country.Ghana:
                case Country.Guinea:
                case Country.GuineaBissau:
                case Country.IvoryCoast:
                case Country.Jamaica:
                case Country.Kenya:
                case Country.Lesotho:
                case Country.Liberia:
                case Country.Malawi:
                case Country.Madagascar:
                case Country.Mali:
                case Country.Mauritania:
                case Country.Morocco:
                case Country.Mozambique:
                case Country.Namibia:
                case Country.NewCaledonia:
                case Country.Niger:
                case Country.Nigeria:
                case Country.PapuaNewGuinea:
                case Country.Rwanda:
                case Country.Senegal:
                case Country.SierraLeone:
                case Country.Somalia:
                case Country.Sudan:
                case Country.Swaziland:
                case Country.Tanzania:
                case Country.Togo:
                case Country.Tunisia:
                case Country.Uganda:
                case Country.Zambia:
                case Country.Zimbabwe:
                    ethnicity = AvatarEthnicity.Black;
                    break;
                case Country.Argentina:
                case Country.Aruba:
                case Country.Bahamas:
                case Country.Barbados:
                case Country.Belize:
                case Country.Bermuda:
                case Country.Bolivia:
                case Country.Brazil:
                case Country.Chile:
                case Country.Colombia:
                case Country.CostaRica:
                case Country.Cuba:
                case Country.DominicanRepublic:
                case Country.Ecuador:
                case Country.ElSalvador:
                case Country.FrenchGuiana:
                case Country.Guatemala:
                case Country.Guyana:
                case Country.Haiti:
                case Country.Honduras:
                case Country.Mauritius:
                case Country.Mexico:
                case Country.Nicaragua:
                case Country.Panama:
                case Country.Paraguay:
                case Country.Peru:
                case Country.PuertoRico:
                case Country.Surinam:
                case Country.Uruguay:
                case Country.Venezuela:
                    ethnicity = AvatarEthnicity.Hispanic;
                    break;
                case Country.Andorra:
                case Country.Australia:
                case Country.Austria:
                case Country.Belarus:
                case Country.Belgium:
                case Country.BosniaHerzegovina:
                case Country.Bulgaria:
                case Country.Canada:
                case Country.Croatia:
                case Country.Cyprus:
                case Country.CzechRepublic:
                case Country.Denmark:
                case Country.Estonia:
                case Country.Finland:
                case Country.France:
                case Country.Germany:
                case Country.Gibraltar:
                case Country.UnitedKingdom:
                case Country.Greece:
                case Country.Hungary:
                case Country.Iceland:
                case Country.Ireland:
                case Country.Italy:
                case Country.Latvia:
                case Country.Liechtenstein:
                case Country.Lithuania:
                case Country.Luxembourg:
                case Country.Macedonia:
                case Country.Maldives:
                case Country.Malta:
                case Country.Moldova:
                case Country.Monaco:
                case Country.Netherlands:
                case Country.NewZealand:
                case Country.Norway:
                case Country.Poland:
                case Country.Portugal:
                case Country.ReunionIsland:
                case Country.Romania:
                case Country.Russia:
                case Country.Scotland:
                case Country.Slovakia:
                case Country.Slovenia:
                case Country.SouthAfrica:
                case Country.Spain:
                case Country.Sweden:
                case Country.Switzerland:
                case Country.Ukraine:
                case Country.UnitedStates:
                case Country.Yugoslavia:
                    ethnicity = AvatarEthnicity.White;
                    break;
                case Country.Bangladesh:
                case Country.Brunei:
                case Country.BurmaMyanmar:
                case Country.Cambodia:
                case Country.CanaryIslands:
                case Country.CaymanIslands:
                case Country.China:
                case Country.HongKong:
                case Country.Indonesia:
                case Country.Japan:
                case Country.Laos:
                case Country.Malaysia:
                case Country.Mongolia:
                case Country.NorthKorea:
                case Country.Philippines:
                case Country.Singapore:
                case Country.SouthKorea:
                case Country.Taiwan:
                case Country.Thailand:
                case Country.Vietnam:
                    ethnicity = AvatarEthnicity.Asian;
                    break;
                case Country.Israel:
                case Country.Jordan:
                    ethnicity = AvatarEthnicity.Jewish;
                    break;
                default:
                    ethnicity = AvatarEthnicity.Indeterminate;
                    break;
            }

            var m3 = from a in Avatars where a.Gender == gender && a.Age == age && a.Ethnicity == ethnicity select a;
            var m2_1 = from a in Avatars where a.Gender == AvatarGender.Indeterminate && a.Age == age && a.Ethnicity == ethnicity select a;
            var m2_2 = from a in Avatars where a.Gender == gender && a.Age == AvatarAge.Indeterminate && a.Ethnicity == ethnicity select a;
            var m2_3 = from a in Avatars where a.Gender == gender && a.Age == age && a.Ethnicity == AvatarEthnicity.Indeterminate select a;
            var m2 = m2_1.Concat(m2_2).Concat(m2_3);
            var m1_12 = from a in Avatars where a.Gender == AvatarGender.Indeterminate && a.Age == AvatarAge.Indeterminate && a.Ethnicity == ethnicity select a;
            var m1_13 = from a in Avatars where a.Gender == AvatarGender.Indeterminate && a.Age == age && a.Ethnicity == AvatarEthnicity.Indeterminate select a;
            var m1_23 = from a in Avatars where a.Gender == gender && a.Age == AvatarAge.Indeterminate && a.Ethnicity == AvatarEthnicity.Indeterminate select a;
            var m1 = m1_12.Concat(m1_13).Concat(m1_23);
            var m0 = from a in Avatars where a.Gender == AvatarGender.Indeterminate && a.Age == AvatarAge.Indeterminate && a.Ethnicity == AvatarEthnicity.Indeterminate select a;
            var m = 
                (from a in m3 select new Tuple<AvatarDescriptor, double>(a, 1))
                .Concat(from a in m2 select new Tuple<AvatarDescriptor, double>(a, 3))
                .Concat(from a in m1 select new Tuple<AvatarDescriptor, double>(a, 7))
                .Concat(from a in m0 select new Tuple<AvatarDescriptor, double>(a, 10));
            var rnd = new Random(user.Uid);
            var result = (from a in m select new Tuple<AvatarDescriptor, double>(a.Item1, rnd.NextDouble() * a.Item2)).OrderBy(a => a.Item2).FirstOrDefault();
            return result != null ? result.Item1.Image : null;
        }

        public static readonly OdigoAvatarConverter Default = new OdigoAvatarConverter();
    }

    public sealed class AvatarDescriptor
    {
        public ImageSource Image { get; set; }
        public AvatarGender Gender { get; set; }
        public AvatarAge Age { get; set; }
        public AvatarEthnicity Ethnicity { get; set; }
    }

    public enum AvatarGender
    {
        Indeterminate,
        Male,
        Female
    }

    public enum AvatarAge
    {
        Indeterminate,
        Young,
        MiddleAged,
        Old
    }

    public enum AvatarEthnicity
    {
        Indeterminate,
        White,
        Black,
        Asian,
        Arab,
        Jewish,
        Hispanic
    }
}
